#include "qobjectlistview.h"

#include "../../libs/sharedLib/pluginloader.h"
#include "../../libs/sharedLib/qwidgetplugin.h"
#include "../../libs/sharedLib/qabstracthost.h"

#include <QItemDelegate>
#include <QPainter>
#include <QApplication>
#include <QPalette>

class QObjectDelegate: public QItemDelegate
{
public :
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

void QObjectDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV3 opt=option;
    QColor c;
    if(!index.data(Qt::UserRole).toBool())
    {
        c=QColor(255,191,239);
        if(opt.features & QStyleOptionViewItemV2::Alternate)
        {
            c=c.lighter(112);
        }
    }
    else
    {

        c=opt.palette.color(QPalette::Dark);
    }



    painter->fillRect(option.rect,c);
    opt.state &=~ QStyle::State_HasFocus;
    QItemDelegate::paint(painter,opt,index);
    opt.palette.setCurrentColorGroup(QPalette::Active);
    QColor color=static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor,&opt));
    painter->setPen(color);

    if(index.column()==0)
    {
        int right=option.direction==Qt::LeftToRight?option.rect.right():option.rect.left();
        painter->drawLine(right,option.rect.y(),right,option.rect.bottom());
    }
}

QSize QObjectDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSize sz=QItemDelegate::sizeHint(option,index);
    sz.setHeight(20);
    return sz;
}

QObjectListView::QObjectListView(QWidget *parent) :
    QTreeWidget(parent)
{
    this->setFrameStyle(QFrame::NoFrame);

    this->setColumnCount(2);

    this->setHeaderLabels(QStringList()<<"name"<<"type");

    setAlternatingRowColors(true);
    setEditTriggers(QAbstractItemView::EditKeyPressed);

    connect(this,SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(clickedItem(QTreeWidgetItem*,int)));

    setItemDelegate(new QObjectDelegate);

    QPalette p=this->palette();
    p.setColor(QPalette::Inactive,QPalette::Highlight,p.color(QPalette::Active,QPalette::Highlight));
    p.setColor(QPalette::Inactive,QPalette::HighlightedText,p.color(QPalette::Active,QPalette::HighlightedText));
    this->setPalette(p);

    connect(this,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,
            SLOT(currentObjectChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
}

void QObjectListView::formAdd(QWidget *wid)
{
    QTreeWidgetItem* item=m_formItems.value(wid);
    if(item!=NULL)
    {
        return;
    }
    SHAREDLIB::QAbstractHost *host;
    connect(wid,SIGNAL(destroyed()),this,SLOT(formDestroyed()));
    item=new QTreeWidgetItem(this);
    item->setText(0,wid->property("objectName").toString());
    m_formItems.insert(wid,item);
    m_itemToWidget.insert(item,wid);
    m_allItems.insert(wid,item);
    item->setData(0,Qt::UserRole,true);
    item->setData(1,Qt::UserRole,true);
    QObjectList list=wid->children();

    host=(SHAREDLIB::QAbstractHost *)wid->property("host").toInt();
    connect(host,SIGNAL(nameChanged()),this,SLOT(nameChanged()));

    QMap<QString,SHAREDLIB::QWidgetPlugin*> plugins=SHAREDLIB::PluginLoader::getPluginLoader()->getWidgetPlugins();
    while(list.size()>0)
    {
        QWidget *w=(QWidget*)list.first();
        if(w->property("host").isValid())
        {
            host=(SHAREDLIB::QAbstractHost *)w->property("host").toInt();
            connect(host,SIGNAL(nameChanged()),this,SLOT(nameChanged()));
            QTreeWidgetItem* temp=m_allItems.value(w->parentWidget());
            item=new QTreeWidgetItem(temp);
            item->setText(0,w->property("objectName").toString());
            QString pluginName=w->property("plugin").toString();
            SHAREDLIB::QWidgetPlugin* plugin=NULL;
            if(pluginName!="")
            {
                plugin=plugins.value(pluginName);
            }
            if(pluginName=="" || plugin==NULL)
            {
                QMapIterator<QString,SHAREDLIB::QWidgetPlugin*> it(plugins);
                while(it.hasNext())
                {
                    it.next();
                    QStringList list=it.value()->supportWidgets();
                    if(list.contains(w->property("type").toString()))
                    {
                        plugin=it.value();
                        break;
                    }
                }
            }

            if(plugin!=NULL)
            {
                SHAREDLIB::WidgetInfo info=plugin->widgetInfo(w->property("type").toString());
                item->setText(1,info.m_name);
                item->setIcon(1,QIcon(info.m_icon));
            }


            m_widgetItems.insert(w,item);
            m_itemToWidget.insert(item,w);
            m_allItems.insert(w,item);
            list+=w->children();
        }
        list.removeFirst();
    }
}

void QObjectListView::clickedItem(QTreeWidgetItem* item,int)
{
    emit selectSignal(m_itemToWidget.value(item));
}

void QObjectListView::formDestroyed()
{
    QWidget* wid=(QWidget*)sender();
    QTreeWidgetItem *item=m_formItems.value(wid);
    m_formItems.remove(wid);
    m_allItems.remove(wid);
    if(item==NULL)
    {
        return;
    }
    m_itemToWidget.remove(item);
    delete item;
}

void QObjectListView::addWidget(QWidget *wid,int index)
{
    if(!wid->property("host").isValid())
    {
        return;
    }

    QWidget *parent=wid->parentWidget();
    while(parent!=NULL)
    {
        if(parent->property("host").isValid())
        {
            break;
        }
    }
    if(parent==NULL)
    {
        return;
    }

    if(m_widgetItems.value(wid)!=NULL)
    {
        return;
    }

    SHAREDLIB::QAbstractHost * host=(SHAREDLIB::QAbstractHost *)wid->property("host").toInt();
    connect(host,SIGNAL(nameChanged()),this,SLOT(nameChanged()));

    QTreeWidgetItem* item=m_allItems.value(parent);
    QTreeWidgetItem* temp=new QTreeWidgetItem(NULL);
    if(index<0)
    {
        index=item->childCount();
    }
    if(index>item->childCount())
    {
        index=item->childCount();
    }
    item->insertChild(index,temp);

    QMap<QString,SHAREDLIB::QWidgetPlugin*> plugins=SHAREDLIB::PluginLoader::getPluginLoader()->getWidgetPlugins();

    temp->setText(0,wid->property("objectName").toString());
    QString pluginName=wid->property("plugin").toString();
    SHAREDLIB::QWidgetPlugin* plugin=NULL;
    if(pluginName!="")
    {
        plugin=plugins.value(pluginName);
    }
    if(pluginName=="" || plugin==NULL)
    {
        QMapIterator<QString,SHAREDLIB::QWidgetPlugin*> it(plugins);
        while(it.hasNext())
        {
            it.next();
            QStringList list=it.value()->supportWidgets();
            if(list.contains(wid->property("type").toString()))
            {
                plugin=it.value();
                break;
            }
        }
    }

    if(plugin!=NULL)
    {
        SHAREDLIB::WidgetInfo info=plugin->widgetInfo(wid->property("type").toString());
        temp->setText(1,info.m_name);
        temp->setIcon(1,QIcon(info.m_icon));
    }

    m_widgetItems.insert(wid,temp);
    m_itemToWidget.insert(temp,wid);
    m_allItems.insert(wid,temp);
}

void QObjectListView::selectWidget(QWidget *wid)
{
    QTreeWidgetItem *item=m_allItems.value(wid);
    if(item!=NULL)
    {
        if(!item->isSelected())
        {
            setCurrentItem(item);
            item->setExpanded(true);
        }
    }
}

void QObjectListView::nameChanged()
{
    SHAREDLIB::QAbstractHost *host=(SHAREDLIB::QAbstractHost *)sender();
    QTreeWidgetItem *item=m_allItems.value((QWidget*)host->object());
    item->setText(0,host->getPropertyValue("objectName").toString());
}

void QObjectListView::currentObjectChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
    if(current==NULL)
    {
        return;
    }
    emit selectSignal(m_itemToWidget.value(current));
}

void QObjectListView::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
{
    QTreeWidgetItem *item=this->itemFromIndex(index);

    QColor c;
    QStyleOptionViewItem opt=options;
    if(m_formItems.values().contains(item))
    {
        c=opt.palette.color(QPalette::Dark);
    }
    else
    {
        c=QColor(255,191,239);
    }


    painter->fillRect(options.rect,c);
    opt.palette.setColor(QPalette::AlternateBase,c.lighter(112));
    QTreeWidget::drawRow(painter,opt,index);

    QColor color=static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor));
    painter->setPen(color);
    painter->drawLine(opt.rect.x(),opt.rect.bottom(),opt.rect.right(),opt.rect.bottom());
}

void QObjectListView::clear_list()
{
    m_formItems.clear();
    m_widgetItems.clear();
    m_allItems.clear();
    m_itemToWidget.clear();
    this->clear();
}

void QObjectListView::widgetRemove(QWidget *wid)
{
    QTreeWidgetItem *item=m_widgetItems.value(wid);
    m_widgetItems.remove(wid);
    m_allItems.remove(wid);
    if(item==NULL)
    {
        return;
    }
    m_itemToWidget.remove(item);
    delete item;
}
